/*
 * Copyright © 2009-2020 Frictional Games
 * 
 * This file is part of Amnesia: The Dark Descent.
 * 
 * Amnesia: The Dark Descent is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version. 

 * Amnesia: The Dark Descent is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Amnesia: The Dark Descent.  If not, see <https://www.gnu.org/licenses/>.
 */

#include "../Common/EdVar.h"
#include "../Common/EdWindowHandler.h"

#include "../Common/EdInput.h"

//--------------------------------------------------------------------


//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// EDITOR VAR BASE
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVar::iEdVar(int aType)
{
	mType = aType;
	mpExtraData = NULL;
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

bool iEdVar::Create(cXmlElement* apElement)
{
	if(apElement==NULL)
		return false;

	msName = cString::To16Char(apElement->GetAttributeString("Name"));
	if(msName.empty())
		return false;

	Log("\tVar 0x%p name %ls - %d chars\n", this, msName.c_str(), msName.size());

	msDefaultValue = cString::To16Char(apElement->GetAttributeString("DefaultValue"));
	msDescription = cString::To16Char(apElement->GetAttributeString("Description"));

	if(msDefaultValue.empty())
		msDefaultValue = cString::To16Char(apElement->GetAttributeString("Value"));

	return true;
}

//--------------------------------------------------------------------------------

iEdVarInput* iEdVar::CreateInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	iEdVarInput* pInput = CreateSpecificInput(apWindow, apParent, apVar);
	if(pInput)
	{
		iEdInput* pEdInput = pInput->GetInput();
		pEdInput->SetStyle(eEdInpStyle_RowLabelOnLeft);
		pEdInput->UpdateLayout();
	}

	return pInput;
}

//--------------------------------------------------------------------------------

cEdVarInstance* iEdVar::CreateInstance()
{
	cEdVarInstance* pInstance = hplNew(cEdVarInstance,(this));
	pInstance->SetValue(msDefaultValue);

	return pInstance;
}

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// EDITOR VAR INPUT BASE
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput::iEdVarInput(cEdVarInstance* apVar, iEdInput* apInput)
{
	mpVar = apVar; 
	mpInput = apInput;
	mpPanel = NULL;

	mpInput->AddCallback(eEdInputCallback_ValueEnter, this, kGuiCallback(OnValueEnter));
	mpInput->GetHandle()->SetToolTip(apVar->GetVarType()->GetDescription());
}

iEdVarInput::~iEdVarInput()
{
	iEdWindow* pWindow = mpInput->GetWindow();
	pWindow->DestroyInput(mpInput);
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

void iEdVarInput::Update()
{
	FetchValueFromVar();
}

//--------------------------------------------------------------------------------

void iEdVarInput::FetchValueFromVar()
{
	mpInput->SetValue(mpVar->GetValue(), false);
}

//--------------------------------------------------------------------------------

void iEdVarInput::CopyValueToVar()
{
	mpVar->SetValue(mpInput->GetValue());
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

bool iEdVarInput::OnValueEnter(iWidget* apWidget, const cGuiMessageData& aData)
{
	if(mpPanel->RunCallback(this)==false)
        CopyValueToVar();

	return true;
}
kGuiCallbackDeclaredFuncEnd(iEdVarInput,OnValueEnter);

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR BOOL
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarBool::cEdVarBool() : iEdVar(eVariableType_Bool)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarBool::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputBool,(apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// EDITOR VAR BOOL INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputBool::cEdVarInputBool(cEdVarInstance* apVar, 
									iEdWindow* apWindow, 
									iWidget* apParent) : iEdVarInput(apVar,
																	 apWindow->CreateInputBool(0,apVar->GetVarType()->GetName(), 
																										 
																										apParent))
{
}


//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR FLOAT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarFloat::cEdVarFloat() : iEdVar(eVariableType_Float)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarFloat::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputFloat,(apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// EDITOR VAR FLOAT INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputFloat::cEdVarInputFloat(cEdVarInstance* apVar,
										   iEdWindow* apWindow,
										   iWidget* apParent) : iEdVarInput(apVar, 
																				apWindow->CreateInputNumber(0,
																											apVar->GetVarType()->GetName(),
																											
																											apParent,
																											50,0.1f))
{
}
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR INT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInt::cEdVarInt() : iEdVar(eVariableType_Int)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarInt::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputInt, (apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR INT INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputInt::cEdVarInputInt(cEdVarInstance* apVar,
									   iEdWindow* apWindow,
									   iWidget* apParent) : iEdVarInput(apVar,
																			apWindow->CreateInputNumber(0,apVar->GetVarType()->GetName(),  apParent, 50, 1))
{
}

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR STRING
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarString::cEdVarString() : iEdVar(eVariableType_String)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarString::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputString, (apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR STRING INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputString::cEdVarInputString(cEdVarInstance* apVar,
											 iEdWindow* apWindow,
											 iWidget* apParent) : iEdVarInput(apVar,
																				  apWindow->CreateInputString(0,apVar->GetVarType()->GetName(),  apParent, 160))
																									
{
}


//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR VECTOR2F
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarVector2f::cEdVarVector2f() : iEdVar(eVariableType_Vec2)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarVector2f::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputVector2f, (apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR VECTOR2F INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputVector2f::cEdVarInputVector2f(cEdVarInstance* apVar,
												 iEdWindow* apWindow,
												 iWidget* apParent) : iEdVarInput(apVar,
																					  apWindow->CreateInputVec2(0,apVar->GetVarType()->GetName(), 
																												 apParent, 50, tWStringList(),eEdInpStyle_RowLabelOnTop, 0.1f))
{
}

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// EDITOR VAR VECTOR3F
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarVector3f::cEdVarVector3f() : iEdVar(eVariableType_Vec3)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarVector3f::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputVector3f, (apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// EDITOR VAR VECTOR3F INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputVector3f::cEdVarInputVector3f(cEdVarInstance* apVar,
												 iEdWindow* apWindow,
												 iWidget* apParent) : iEdVarInput(apVar,
																					  apWindow->CreateInputVec3(0,apVar->GetVarType()->GetName(),  apParent,50,tWStringList(), eEdInpStyle_RowLabelOnTop, 0.1f))
{
}

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR COLOR
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarColor::cEdVarColor() : iEdVar(eVariableType_Color)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarColor::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputColor, (apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR COLOR INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputColor::cEdVarInputColor(cEdVarInstance* apVar,
										   iEdWindow* apWindow,
										   iWidget* apParent) : iEdVarInput(apVar,
																				apWindow->CreateInputColor(0, apVar->GetVarType()->GetName(),  apParent))
{
}

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR ENUM
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarEnum::cEdVarEnum() : iEdVar(eVariableType_Enum)
{
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarEnum::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	return hplNew(cEdVarInputEnum, (apVar, apWindow, apParent));
}

//--------------------------------------------------------------------------------

bool cEdVarEnum::Create(cXmlElement* apElement)
{
	if(iEdVar::Create(apElement)==false)
		return false;

	int lCurrentValue=-1;

	int i=0;
	cXmlNodeListIterator it = apElement->GetChildIterator();
	while(it.HasNext())
	{
		cXmlElement* pValue = it.Next()->ToElement();
		tWString sValue = cString::To16Char(pValue->GetAttributeString("Name"));

		if(msDefaultValue==sValue)
			lCurrentValue = i;
		mvValues.push_back(sValue);

		++i;
	}

	if(lCurrentValue==-1 && mvValues.empty()==false)
		msDefaultValue = mvValues[0];

	return true;
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR ENUM INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputEnum::cEdVarInputEnum(cEdVarInstance* apVar,
								 iEdWindow* apWindow,
								 iWidget* apParent) : iEdVarInput(apVar,
																	apWindow->CreateInputEnum(0, apVar->GetVarType()->GetName(), apParent))
{
	cEdInputEnum* pInput = static_cast<cEdInputEnum*>(mpInput);
	cEdVarEnum* pEnum = static_cast<cEdVarEnum*>(apVar->GetVarType());

	const tWStringVec& vValues = pEnum->GetEnumValues();
	for(size_t i=0;i<vValues.size();++i)
		pInput->AddValue(vValues[i]);

	mpInput->SetValue(mpVar->GetValue(), false, true);
}

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// EDITOR VAR FILE
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarFile::cEdVarFile() : iEdVar(eVariableType_String)
{
}

//--------------------------------------------------------------------------------

bool cEdVarFile::Create(cXmlElement* apElement)
{
	if(iEdVar::Create(apElement)==false)
		return false;

//	mResType = GetBrowserTypeFromElement(apElement);
/*	if(mResType==eEdResourceType_LastEnum)
	{
		tString sExtensions = apElement->GetAttributeString("Extensions");
		tStringVec vExtensions;
		vExtensions = cString::GetStringVec(sExtensions, vExtensions);
		for(int i=0;i<(int)vExtensions.size();++i)
			mlstExtensions.push_back(cString::To16Char(vExtensions[i]));
	}
*/
	return true;
}

//--------------------------------------------------------------------------------

/*
eEdResourceType cEdVarFile::GetBrowserTypeFromElement(cXmlElement* apElement)
{
	tString sType = apElement->GetAttributeString("ResType", "Custom");

	tString vResStrings[] = 
	{
		"Material",
		"Texture",
		"Sound",
		"ParticleSystem",
		"Entity",
		"Model",

		""
	};

	for(int i=0;vResStrings[i]!="";++i)
	{
		const tString& sResType = vResStrings[i];
		if(sType==sResType)
			return (eEdResourceType)i;
	}

	return eEdResourceType_LastEnum;
}
*/
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

iEdVarInput* cEdVarFile::CreateSpecificInput(iEdWindow* apWindow, iWidget* apParent, cEdVarInstance* apVar)
{
	cEdVarInputFile* pInput = hplNew(cEdVarInputFile, (apVar, apWindow, apParent));
	cEdInputFile* pInputFile = (cEdInputFile*)pInput->GetInput();
//	pInputFile->SetBrowserType(mResType);
	tWStringListIt it = mlstExtensions.begin();
	for(;it!=mlstExtensions.end();++it)
		pInputFile->AddFileType(*it);

	return pInput;
}

//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CUSTOM VAR FILE INPUT
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------

cEdVarInputFile::cEdVarInputFile(cEdVarInstance* apVar,
										 iEdWindow* apWindow,
										 iWidget* apParent) : iEdVarInput(apVar,
																			apWindow->CreateInputFile(0,apVar->GetVarType()->GetName(), _W(""), apParent, 100))
																									
{
	cEdInputFile* pInput = (cEdInputFile*)mpInput;
	cEdVarFile* pFile = (cEdVarFile*)apVar->GetVarType();
}


//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------


//--------------------------------------------------------------------
//--------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////
// VAR INSTANCE
/////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------

cEdVarInstance::cEdVarInstance(iEdVar* apVar)
{
	mpVar = apVar;
}

//--------------------------------------------------------------------

iEdVarInput* cEdVarInstance::CreateInput(iEdWindow* apWindow, iWidget* apParent)
{
	return mpVar->CreateInput(apWindow, apParent, this);
}

//-------------------------------------------------------------------

const tWString& cEdVarInstance::GetName()
{
	return mpVar->GetName();
}

//-------------------------------------------------------------------

bool cEdVarInstance::SetValue(const tWString& asValue)
{
	if(msValue==asValue)
		return false;

	msValue = asValue;

	return true;
}

//-------------------------------------------------------------------
//-------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////
// CLASS - CONSTRUCTORS
/////////////////////////////////////////////////////////////////////

//-------------------------------------------------------------------

int				iEdClass::mlCreatedClasses = 0;
tVarCreatorMap	iEdClass::mmapVarCreators = tVarCreatorMap();
iEdVarCreator*	iEdClass::mpDefaultVarCreator = NULL;

//-------------------------------------------------------------------

iEdClass::iEdClass()
{
	mpParent = NULL;

	if(mlCreatedClasses==0)
	{
		AddVarCreator(hplNew(cEdVarBoolCreator,()));
		AddVarCreator(hplNew(cEdVarFloatCreator,()));
		AddVarCreator(hplNew(cEdVarIntCreator,()));
		AddVarCreator(hplNew(cEdVarVector2fCreator,()));
		AddVarCreator(hplNew(cEdVarVector3fCreator,()));
		AddVarCreator(hplNew(cEdVarStringCreator,()), true);
		AddVarCreator(hplNew(cEdVarColorCreator,()));
		AddVarCreator(hplNew(cEdVarEnumCreator, ()));
	}
	++mlCreatedClasses;
}

iEdClass::~iEdClass()
{
	--mlCreatedClasses;
	if(mlCreatedClasses==0)
	{
		STLMapDeleteAll(mmapVarCreators);
		mpDefaultVarCreator = NULL;
	}

	STLMapDeleteAll(mmapVars);
}


//-------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////
// CLASS - PUBLIC METHODS
/////////////////////////////////////////////////////////////////////

//-------------------------------------------------------------------

const tWString& iEdClass::GetFullName()
{
	if(msFullName.empty())
	{
		if(mpParent) 
			msFullName = mpParent->GetFullName() + _W(".");

		msFullName += msName;
	}

	return msFullName;
}

//-------------------------------------------------------------------

cEdClassInstance* iEdClass::CreateInstance()
{
	cEdClassInstance* pInstance = hplNew(cEdClassInstance,(this));
    CreateVariableInstances(pInstance);

	return pInstance;
}


//-------------------------------------------------------------------

void iEdClass::AddChild(iEdClass* apChild)
{
	if(apChild)
	{
		apChild->SetParent(this);
		mvChildren.push_back(apChild);
	}
}

//-------------------------------------------------------------------

iEdVarInputPanel* iEdClass::CreateInputPanel(cEdClassInstance* apClass)
{
	return hplNew(iEdVarInputPanel,(apClass));
}

//-------------------------------------------------------------------

int iEdClass::GetNumChildren()
{
	return (int)mvChildren.size();
}

iEdClass* iEdClass::GetChild(int alIdx)
{
	if(alIdx<0 || alIdx>=GetNumChildren())
		return NULL;

	return mvChildren[alIdx];
}

//-------------------------------------------------------------------

void iEdClass::CreateVariableInstances(cEdClassInstance* apInstance)
{
	if(mpParent)
		mpParent->CreateVariableInstances(apInstance);

	AddVariablesToInstance(apInstance);
}

//-------------------------------------------------------------------

void iEdClass::AddVarCreator(iEdVarCreator* apCreator, bool abDefault)
{
	if(apCreator)
	{
		mmapVarCreators.insert(tVarCreatorMap::value_type(apCreator->GetType(), apCreator));
		if(abDefault)	mpDefaultVarCreator = apCreator;
	}
}

//-------------------------------------------------------------------

iEdVar* iEdClass::CreateVariable(const tString& asType)
{
	iEdVar* pVar = NULL;

	tVarCreatorMapIt it = mmapVarCreators.find(asType);
	if(it!=mmapVarCreators.end())
	{
		iEdVarCreator* pCreator = it->second;
		pVar = pCreator->CreateVar();
	}
	else
	{
		if(mpDefaultVarCreator) pVar = mpDefaultVarCreator->CreateVar();
		else
			Error("No proper creator for variable type %s found\n", asType.c_str());
	}

	return pVar;
}

//-------------------------------------------------------------------

bool iEdClass::AddVariablesFromElement(tEdVarVec& avVars, cXmlElement* apElement)
{
	if(apElement==NULL)
		return false;

	cXmlNodeListIterator it = apElement->GetChildIterator();
	while(it.HasNext())
	{
		cXmlElement* pVarData = it.Next()->ToElement();

		iEdVar* pVar = CreateVariableFromElement(pVarData);
		if(pVar)
			avVars.push_back(pVar);
		else
			return false;
	}

	return true;
}

//-------------------------------------------------------------------

iEdVar* iEdClass::GetVariable(const tEdVarVec& avVars, const tWString& asName)
{
	for(size_t i=0;i<avVars.size();++i)
	{
		iEdVar* pVar = avVars[i];
		if(pVar->GetName()==asName)
			return pVar;
	}

	return NULL;
}


/*

//-------------------------------------------------------------------

iEdVar* iEdClass::CreateClassSpecificVariableFromElement(cXmlElement* apElement)
{
	return CreateVariableFromElement(apElement);
}

//-------------------------------------------------------------------
*/
iEdVar* iEdClass::CreateVariableFromElement(cXmlElement* apElement)
{
	if(apElement==NULL)
		return NULL;

	iEdVar* pVar = NULL;

	///////////////////////////////////////////
	// Create Variable according to type
	tString sType = apElement->GetAttributeString("Type");
	pVar = CreateVariable(sType);

	////////////////////////////////////////////
	// Set up variable
	if(pVar) pVar->Create(apElement);

	return pVar;
}

//-------------------------------------------------------------------

/*
iEdClass* iEdClass::GetClassByIdx(const tEditorClassVec& avClasses, int alIdx)
{
	if(alIdx<0 || alIdx>=(int)avClasses.size())
		return NULL;

	return avClasses[alIdx];
}

//-------------------------------------------------------------------

iEdClass* iEdClass::GetClassByName(const tEditorClassVec& avClasses, const tString& asName)
{
	for(int i=0;i<(int)avClasses.size();++i)
	{
		iEdClass* pClass = avClasses[i];
		if(pClass->GetName()==asName)
			return pClass;
	}

	return NULL;
}
*/
//-------------------------------------------------------------------

/*
void iEdClass::DumpVarsOnInstance(const tEditorVarVec& avVars, cEdClassInstance* apInstance)
{
	for(int i=0;i<(int)avVars.size();++i)
	{
		iEdVar* pVar = avVars[i];
		cEdVarInstance* pVarInstance = pVar->CreateInstance();

		apInstance->AddVarInstance(pVarInstance);
	}
}
*/
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------

cEdClassInstance::cEdClassInstance(iEdClass* apClass)
{
	mpClass = apClass;
}

cEdClassInstance::~cEdClassInstance()
{
	STLDeleteAll(mvVars);
}

//-------------------------------------------------------------------

void cEdClassInstance::AddVarInstance(cEdVarInstance* apVar)
{
	if(apVar==NULL) return;

	// override any previous var with same name
	for(size_t i=0;i<mvVars.size();++i)
	{
		cEdVarInstance* pVar = mvVars[i];
		if(pVar->GetName() == apVar->GetName())
		{
			hplDelete(pVar);
			mvVars[i] = apVar;

			return;
		}
	}

	mvVars.push_back(apVar);
}

//-------------------------------------------------------------------

int cEdClassInstance::GetVarInstanceNum()
{
	return (int)mvVars.size();
}

//-------------------------------------------------------------------

cEdVarInstance* cEdClassInstance::GetVarInstance(int alIndex)
{
	if(alIndex<0 || alIndex>=GetVarInstanceNum())
		return NULL;

	cEdVarInstance* pVar = mvVars[alIndex];

	return pVar;
}

cEdVarInstance* cEdClassInstance::GetVarInstance(const tWString& asName)
{
	for(int i=0;i<GetVarInstanceNum();++i)
	{
		cEdVarInstance* pVar = mvVars[i];
		if(pVar->GetName()==asName)
			return pVar;
	}

	return NULL;
}

//-------------------------------------------------------------------

bool cEdClassInstance::SetVarValue(const tWString& asName, const tWString& asValue)
{
	cEdVarInstance* pVar = GetVarInstance(asName);
	if(pVar) return pVar->SetValue(asValue);

	return false;
}

//-------------------------------------------------------------------

void cEdClassInstance::Load(cXmlElement* apElement)
{
	cXmlNodeListIterator it = apElement->GetChildIterator();
	while(it.HasNext())
	{
		cXmlElement* pValue = it.Next()->ToElement();
		SetVarValue(cString::To16Char(pValue->GetAttributeString("Name")),
					cString::To16Char(pValue->GetAttributeString("Value")));
	}
}

//-------------------------------------------------------------------

void cEdClassInstance::Save(cXmlElement* apElement)
{
	for(int i=0;i<GetVarInstanceNum();++i)
	{
		cEdVarInstance* pVar = GetVarInstance(i);
		cXmlElement* pXmlVar = apElement->CreateChildElement("Var");
		pXmlVar->SetAttributeString("Name", cString::To8Char(pVar->GetName()));
		pXmlVar->SetAttributeString("Value", cString::To8Char(pVar->GetValue()));
	}
}

//-------------------------------------------------------------------

void cEdClassInstance::LoadValuesFromMap(const tVarValueMap& amapValues)
{
	for(int i=0;i<GetVarInstanceNum();++i)
	{
		cEdVarInstance* pVar = GetVarInstance(i);
		tVarValueMap::const_iterator it = amapValues.find(pVar->GetName());
		if(it!=amapValues.end())
			pVar->SetValue(it->second);
	}
}

//-------------------------------------------------------------------

void cEdClassInstance::SaveValuesToMap(tVarValueMap& amapValues)
{
	for(int i=0;i<GetVarInstanceNum();++i)
	{
		cEdVarInstance* pVar = GetVarInstance(i);
		amapValues[pVar->GetName()] = pVar->GetValue();
	}
}

//-------------------------------------------------------------------

void cEdClassInstance::LoadFromResourceVarsObject(cResourceVarsObject* apObject)
{
	if(apObject==NULL) return;

	for(int i=0;i<GetVarInstanceNum();++i)
	{
		cEdVarInstance* pVar = GetVarInstance(i);
		tString sName = cString::To8Char(pVar->GetName());
		tString sOldValue = cString::To8Char(pVar->GetValue());

		tString sValue = apObject->GetVarString(sName, sOldValue);

		pVar->SetValue(cString::To16Char(sValue));
	}
}

//-------------------------------------------------------------------

cEdClassInstance* cEdClassInstance::CreateCopy()
{
	cEdClassInstance* pCopy = CreateSpecificCopy();
	pCopy->CopyFromInstance(this);
	
	return pCopy;
}

//-------------------------------------------------------------------

void cEdClassInstance::CopyFromInstance(cEdClassInstance* apInstance)
{
	for(int i=0;i<GetVarInstanceNum();++i)
	{
		cEdVarInstance* pVar = GetVarInstance(i);
		cEdVarInstance* pVarToCopy = apInstance->GetVarInstance(pVar->GetName());
		if(pVarToCopy)
			pVar->SetValue(pVarToCopy->GetValue());
	}
}

//-------------------------------------------------------------------

iEdVarInputPanel* cEdClassInstance::CreateInputPanel(iEdWindow* apWindow, iWidget* apParent, bool abRows)
{
	iEdVarInputPanel* pPanel = mpClass->CreateInputPanel(this);

	pPanel->SetDeployInputsOnRows(abRows);
	pPanel->Create(apWindow, apParent);

	return pPanel;
}

//-------------------------------------------------------------------
//-------------------------------------------------------------------

iEdVarInputPanel::iEdVarInputPanel(cEdClassInstance* apClass)
{
	mpClass = apClass;
	mpHandle = NULL;

	mpCallback = NULL;

	mbDeployInputsOnRows = false;
}

//-------------------------------------------------------------------

iEdVarInputPanel::~iEdVarInputPanel()
{
	STLDeleteAll(mvInputs);

	cGuiSet* pSet = mpHandle->GetSet();
	pSet->DestroyWidget(mpHandle);
}

//-------------------------------------------------------------------

void iEdVarInputPanel::Create(iEdWindow* apWindow, iWidget* apWidget)
{
	cGuiSet* pSet = apWindow->GetGuiSet();
	mpHandle = pSet->CreateWidgetFrame(0,apWidget->GetSize()-4,false, apWidget, false, true);
	mpHandle->SetName("InputPanel");

	cVector3f vPos = cVector3f(0,0,0.1f);

	float fContainerWidth = apWidget->GetSize().x;

	for(int i=0;i<mpClass->GetVarInstanceNum();++i)
	{
		cEdVarInstance* pVar = mpClass->GetVarInstance(i);
		iEdVarInput* pInput = pVar->CreateInput(apWindow, mpHandle);
		if(pInput)
		{
			if(mbDeployInputsOnRows)
			{
				if(vPos.x+pInput->GetInput()->GetSize().x> fContainerWidth)
				{
					vPos.x = 0;
					vPos.y += 50;
				}
			}

			pInput->SetPanel(this);

			pInput->GetInput()->SetPosition(vPos);
			pInput->GetInput()->SetStyle(eEdInpStyle_ColumnLabelOnTop);
			pInput->GetInput()->UpdateLayout();

			mvInputs.push_back(pInput);

			if(mbDeployInputsOnRows)
				vPos.x += pInput->GetInput()->GetSize().x + 15.0f;
			else
				vPos.y += pInput->GetInput()->GetSize().y + 10.0f;
		}
	}
}

//-------------------------------------------------------------------

void iEdVarInputPanel::Update()
{
	for(size_t i=0;i<mvInputs.size();++i)
	{
		iEdVarInput* pInput = mvInputs[i];

		pInput->Update();
	}
}

//-------------------------------------------------------------------

void iEdVarInputPanel::SetCallback(void* apObject, tEdVarInputPanelCallback apCallback)
{
	mpCallbackObject = apObject;
	mpCallback = apCallback;
}

//-------------------------------------------------------------------

bool iEdVarInputPanel::RunCallback(iEdVarInput* apInput)
{
	if(mpCallback==NULL)
		return false;

	return mpCallback(mpCallbackObject, apInput);
}

//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------

